#include  "gtest/gtest.h"

#include "infra_list.h"

TEST(listTest, listCreateDestroy)
{
    int32_t ret = 0;
    int32_t list_num = 50;
    infra_list_handle handle = NULL;

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);
}

TEST(listTest, listPushPop0)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);
    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
    }

    for (idx = 0; idx < list_num; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx]));
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

TEST(listTest, listPushPop1)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);
    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_front(handle, p[idx]);
    }

    for (idx = 0; idx < list_num; idx++) {
        pitem = (int32_t *)infra_list_pop_back(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx]));
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

TEST(listTest, listPushPop2)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);
    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_front(handle, p[idx]);
    }

    for (idx = 0; idx < list_num; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[list_num - 1 - idx]));
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

TEST(listTest, listPushPop3)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num + 1; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);
    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_front(handle, p[idx]);
    }

    ret = infra_list_push_front(handle, p[50]);
    EXPECT_NE(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[list_num - 1 - idx]));
    }

    pitem = (int32_t *)infra_list_pop_front(handle, -1);
    EXPECT_TRUE(pitem == NULL);

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

TEST(listTest, listPushPop4)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);

    pitem = (int32_t *)infra_list_pop_front(handle, 30);
    EXPECT_TRUE(pitem == NULL);

    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
    }

    for (idx = 0; idx < list_num; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, 30);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx]));
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

TEST(listTest, listInsertPrev)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }
    void *pgolden[list_num] = {p[0], p[1], p[2], p[49], p[3], p[4]};

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);

    for (idx = 0; idx < 5; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
    }

    ret = infra_list_insert_prev(handle, p[3], p[49]);
    EXPECT_EQ(0, ret);

    ret = infra_list_insert_prev(handle, NULL, p[49]);
    EXPECT_NE(0, ret);

    for (idx = 0; idx < 6; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(pgolden[idx]));
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

TEST(listTest, listInsertNext)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }
    void *pgolden[list_num] = {p[0], p[1], p[2], p[3], p[49], p[4]};

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);

    for (idx = 0; idx < 5; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
    }

    ret = infra_list_insert_next(handle, p[3], p[49]);
    EXPECT_EQ(0, ret);

    ret = infra_list_insert_next(handle, NULL, p[49]);
    EXPECT_NE(0, ret);

    for (idx = 0; idx < 6; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(pgolden[idx]));
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

TEST(listTest, listRemove)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);

    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
    }

    ret = infra_list_remove(handle, p[3]);
    EXPECT_EQ(0, ret);

    for (idx = 0; idx < list_num - 1; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        if (idx < 3) {
            EXPECT_EQ(*pitem, *(int32_t *)(p[idx]));
        } else {
            EXPECT_EQ(*pitem, *(int32_t *)(p[idx + 1]));
        }
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

TEST(listTest, listCleanup)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);

    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
    }

    for (idx = 0; idx < list_num - 10; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
    }

    ret = infra_list_cleanup(handle);
    EXPECT_EQ(ret, 0);

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

TEST(listTest, listSetDepth0)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(10, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);

    for (idx = 0; idx < 10; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
        EXPECT_EQ(0, ret);
    }

    ret = infra_list_push_back(handle, p[1]);
    EXPECT_NE(0, ret);

    for (idx = 0; idx < 10; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx]));
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

TEST(listTest, listSetDepth1)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(10, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);

    for (idx = 0; idx < 10; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
        EXPECT_EQ(0, ret);
    }

    ret = infra_list_set_depth(handle, 5);
    EXPECT_EQ(0, ret);

    ret = infra_list_push_back(handle, p[1]);
    EXPECT_NE(0, ret);

    for (idx = 0; idx < 5; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx + 5]));
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

#if 0
int32_t list_giveback_callback(void *puserdata, void *pdata)
{
    int32_t *pitem = (int32_t *)NULL;

    pitem = (int32_t *)pdata;
    *pitem = *pitem + 5;
    // printf("pitem:%d\n", *pitem);

    return 0;
}

TEST(listTest, listGivebackCb0)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(5, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);

    ret = infra_list_register_giveback_callback(handle, list_giveback_callback, p);
    EXPECT_EQ(0, ret);

    for (idx = 0; idx < 10; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
        EXPECT_EQ(0, ret);
    }

    for (idx = 0; idx < 5; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx + 5]));
    }

    for (idx = 0; idx < 5; idx++) {
        pitem = (int32_t *)p[idx];
        EXPECT_EQ(*pitem, 5 + idx);
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}
#endif

int32_t list_notify_callback(void *puserdata, void *pdata)
{
    int32_t *pnt_num = (int32_t *)puserdata;

    *pnt_num = (*pnt_num) + 1;
    // printf("pnt_num:%p, nt_num:%d\n", pnt_num, *pnt_num);

    return 0;
}

TEST(listTest, listNotifyCb0)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t nt_num = 0;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(5, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);

    ret = infra_list_register_notify_callback(handle, list_notify_callback, &nt_num);
    EXPECT_EQ(0, ret);

    for (idx = 0; idx < 5; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
        EXPECT_EQ(0, ret);
    }

    for (idx = 0; idx < 5; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx]));
    }

    EXPECT_EQ(nt_num, 5);

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

void list_travel_callback(void *puserdata, void *pdata)
{
    int32_t *pitem = (int32_t *)pdata;
    *pitem = *pitem + 5;
    // printf("pitem:%d\n", *pitem);

    return;
}

TEST(listTest, listTravel)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);
    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
    }

    infra_list_travel(handle, list_travel_callback, p);

    for (idx = 0; idx < list_num; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx]));
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

bool list_find_callback(void *puserdata, void *pdata)
{
    int32_t *pitem = (int32_t *)pdata;

    if (*pitem == 34) {
        return true;
    }

    return false;
}

TEST(listTest, listFind)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);
    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
    }

    pitem = (int32_t *)infra_list_find(handle, list_find_callback, p);
    ASSERT_TRUE((pitem != NULL));
    EXPECT_EQ(*pitem, 34);

    for (idx = 0; idx < list_num; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx]));
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

TEST(listTest, listFront)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE((handle != NULL));
    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
    }

    pitem = (int32_t *)infra_list_front(handle);
    ASSERT_TRUE((pitem != NULL));
    EXPECT_EQ(*pitem, 0);

    for (idx = 0; idx < list_num; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx]));
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

TEST(listTest, listBack)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE((handle != NULL));
    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
    }

    pitem = (int32_t *)infra_list_back(handle);
    ASSERT_TRUE((pitem != NULL));
    EXPECT_EQ(*pitem, 49);

    for (idx = 0; idx < list_num; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx]));
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }
}

TEST(listTest, listEmpty)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);
    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
    }

    for (idx = 0; idx < list_num; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx]));
    }

    EXPECT_TRUE(infra_list_empty(handle));

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }

}

TEST(listTest, listSize)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);
    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
    }

    EXPECT_TRUE(infra_list_size(handle) == list_num);

    for (idx = 0; idx < list_num; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx]));
    }

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }

}

TEST(listTest, listGetStat)
{
    int32_t ret = 0, idx = 0, list_num = 50;
    int32_t *pitem = (int32_t *)NULL;
    void *p[list_num] = {NULL};
    void *data = NULL;
    infra_list_handle handle = NULL;
    infra_list_stat_info_t stat_info = {0};

    for (idx = 0; idx < list_num; idx++) {
        p[idx] = malloc(sizeof(int32_t) * 4);
        *(int32_t *)(p[idx]) = idx;
        pitem = (int32_t *)p[idx];
    }

    handle = infra_list_create(list_num, list_num, true, "test");
    ASSERT_TRUE(handle != NULL);
    for (idx = 0; idx < list_num; idx++) {
        ret = infra_list_push_back(handle, p[idx]);
    }

    EXPECT_EQ(0, infra_list_get_stat(handle, &stat_info));
    EXPECT_EQ(list_num, stat_info.in_count);
    EXPECT_EQ(0, stat_info.out_count);
    EXPECT_EQ(list_num, stat_info.stash_count);

    for (idx = 0; idx < list_num; idx++) {
        pitem = (int32_t *)infra_list_pop_front(handle, -1);
        ASSERT_TRUE(pitem != NULL);
        EXPECT_EQ(*pitem, *(int32_t *)(p[idx]));
    }

    EXPECT_EQ(0, infra_list_get_stat(handle, &stat_info));
    EXPECT_EQ(list_num, stat_info.in_count);
    EXPECT_EQ(list_num, stat_info.out_count);
    EXPECT_EQ(0, stat_info.stash_count);

    ret = infra_list_destroy(handle);
    EXPECT_EQ(ret, 0);

    for (idx = 0; idx < list_num; idx++) {
        free(p[idx]);
    }

}
